
#include "nane/SoundSystem/SoundSourceImpl_.h"
#include "nane/core/assert.h"

namespace nane
{
    ////////////////////////////////////////////////////////////////////////////////////////////////
    SoundSource::Implementation::Implementation( SoundSystem::Implementation* _creator, ISoundSource* _interface )
        : SubSystemProductImpl<SoundSource::Implementation, SoundSystem::Implementation, ISoundSource*>( _creator, _interface )
        , positionMs( 0 )
        , lengthMs( 0 )
        , state( EState::Stopped )
    {
        NANE_ASSERT( interface != NULL, "ISoundSource interface must be valid" );
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    SoundSource::Implementation::~Implementation()
    {
        if (state == EState::Playing
                || state == EState::PendingStop)
        {
            creator->interface->Stop(interface);
            creator->UnregisterUpdate(this);
        }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    bool SoundSource::Implementation::Update( uint32 _ms )
    {
        bool needMoreUpdate = true;
        switch( state.raw_value() )
        {
        case EState::Stopped:
            break;
        case EState::PendingPlay:
            state = EState::Playing;
            creator->interface->Play(interface, positionMs);
            break;
        case EState::Playing:
            positionMs = std::min(positionMs + _ms, lengthMs);
            if( positionMs == lengthMs )
            {
                state = EState::Stopped;
                positionMs = 0;
                creator->interface->Stop(interface);
                needMoreUpdate = false;
            }
            break;
        case EState::PendingStop:
            state = EState::Stopped;
            creator->interface->Stop(interface);
            needMoreUpdate = false;
            break;
        default:
            ;
        }
        return needMoreUpdate;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
}   // namespace nane
